<?php

namespace App\Api\Controllers\LeshuaUnion;

use App\Api\Controllers\LeshuaUnion\BaseController as base;
use App\Exceptions\BizException;
use Illuminate\Support\Facades\Log;
use function EasyWeChat\Kernel\Support\get_client_ip;

class PayController extends BaseController
{
    public function __construct()
    {

    }


    public function scan_pay($data, $config)
    {
        try {
            $params = [
                "service" => "upload_authcode",
                "t0" => 0,
                "sign_type" => "MD5",
                "auth_code" => $data["code"],
                "merchant_id" => $data["mch_id"],
                "third_order_id" => $data["out_trade_no"],
                "amount" => bcmul((string)$data["total_amount"], (string)100),
                "notify_url" => url("api/leshuaunion/pay_notify_url"),
                "client_ip" => get_client_ip(),
                "nonce_str" => (string)(time() . rand(1000, 9999)),
                "terminal_info" => json_encode([
                    "device_type" => "11",
                    "serial_num" => "lhsd" . $data["mch_id"],
                ])
            ];
            if (isset($data["goods_detail"]) && !empty($data["goods_detail"])) {
                $params["goods_detail"] = $data["goods_detail"];
            }
            //
            $params["sign"] = $this->createSign($params, $config->key);
            $base = base::getInstance();
//            $reqBody = $base->params($params, $data);
            $ret = $base->build($base::SCAN_PAY, $params, 'scan_pay');
            if (empty($ret) || !is_array($ret) || !isset($ret["resp_code"])) {
                throw new BizException("请求失败");
            }
            if ($ret["resp_code"] != "0") {
                throw new BizException($ret["resp_msg"]);
            }
            if (isset($ret['result_code']) && $ret["result_code"] == 0) {
                //支付成功
                //PayResult 0成功，非0失败
                if ($ret['status'] == 2) { //支付成功
                    if ($data['ways_source'] == 'weixin' && isset($ret['promotion_detail'])) {
                        \App\Common\PaySuccessAction::addCoupon($data['out_trade_no'], $ret['promotion_detail'], 'pay');
                    }
                    return [
                        'status' => 1,
                        'message' => '支付成功',
                        'data' => [
                            "status" => $ret["status"],
                            "total_amount" => bcdiv((string)$params["amount"], "100", 2),
                            "pay_amount" => bcdiv((string)($ret["buyer_pay_amount"] ?? $params["amount"]), "100", 2),
                            "pay_time" => $ret["pay_time"] ?? date("Y-m-d H:i:s", time()),
                            "discount_amount" => $ret["discount_amount"] ?? 0,
                            "buyer_id" => $ret["sub_openid"] ?? "",
                            "trade_no" => $ret["out_transaction_id"] ?? "",
                            "other_no" => $ret["leshua_order_id"] ?? "",
                            "pay_ways" => $ret["pay_way"] ?? ""
                        ]
                    ];

                } else if ($ret['status'] == 0) {
                    return [
                        'status' => 2,
                        'message' => '支付中',
                        'data' => [
                            "status" => $ret["status"],
                            "total_amount" => bcdiv((string)($params["amount"] ?? 0), "100", 2),
                            "pay_amount" => bcdiv((string)($ret["buyer_pay_amount"] ?? ($params["amount"] ?? 0)), "100", 2),
                            "pay_time" => "",
                            "discount_amount" => $ret["discount_amount"] ?? 0,
                            "buyer_id" => $ret["sub_openid"] ?? "",
                            "trade_no" => $ret["out_transaction_id"] ?? "",
                            "other_no" => $ret["leshua_order_id"] ?? "",
                            "pay_ways" => $ret["pay_way"] ?? ""
                        ]
                    ];
                } else {
                    $message = $ret['error_msg'] ?? "支付失败";
                    return [
                        'status' => 3,
                        'message' => $message,
                        "data" => [
                            "status" => $ret["status"],
                            "total_amount" => bcdiv((string)($params["amount"] ?? 0), "100", 2),
                            "pay_amount" => bcdiv((string)($ret["buyer_pay_amount"] ?? ($params["amount"] ?? 0)), "100", 2),
                            "pay_time" => "",
                            "discount_amount" => $ret["discount_amount"] ?? 0,
                            "buyer_id" => $ret["sub_openid"] ?? "",
                            "trade_no" => $ret["out_transaction_id"] ?? "",
                            "other_no" => $ret["leshua_order_id"] ?? "",
                            "pay_ways" => $ret["pay_way"] ?? ""
                        ]
                    ];
                }
            } else {
                return [
                    'status' => 3,
                    'message' => $ret["error_msg"] ?? "支付异常",
                ];
            }
        } catch (\Exception $ex) {
            return [
                'status' => 3,
                'message' => $ex->getMessage() . ' | ' . $ex->getLine(),
            ];
        }
    }


    //查询订单 0-系统错误 1-成功 2-正在支付 3-失败 4.已经退款
    public function order_query($data, $config)
    {
        try {
            $params = [
                "service" => "query_status",
                "sign_type" => "MD5",
                "merchant_id" => $data["mch_id"],
                "third_order_id" => $data['out_trade_no'],
//                "leshua_order_id"=>$data["other_no"],
                "nonce_str" => (string)time() . rand(1000, 9999),
            ];
            $params["sign"] = $this->createSign($params, $config->key);
            $base = base::getInstance();
            $ret = $base->build($base::QUERY_ORDER, $params, 'order_query');
            if (empty($ret) || !is_array($ret) || !isset($ret["resp_code"])) {
                throw new BizException("请求失败");
            }
            if ($ret["resp_code"] != "0") {
                throw new BizException($ret["resp_msg"]);
            }
            if (isset($ret['result_code']) && $ret["resp_code"] == 0) {

                if (!isset($ret['status'])) {
                    return [
                        'status' => 3,
                        'message' => '支付异常',
                    ];
                } else if ($ret['status'] == 2) { //支付成功
                    if ($data['ways_source'] == 'weixin' && isset($ret['promotion_detail'])) {
                        Log::channel("goods")->info("leshuaunion_promotion_detail", [
                            "data" => $ret['promotion_detail']
                        ]);
                        \App\Common\PaySuccessAction::addCoupon($data['out_trade_no'], $ret['promotion_detail'], 'query');
                    }
                    return [
                        'status' => 1,
                        'message' => '支付成功',
                        'data' => [
                            "status" => $ret["status"],
                            "total_amount" => bcdiv((string)($ret["amount"] ?? 0), "100", 2),
                            "pay_amount" => bcdiv((string)($ret["buyer_pay_amount"] ?? $ret["amount"]), "100", 2),
                            "pay_time" => $ret["pay_time"] ?? date("Y-m-d H:i:s", time()),
                            "discount_amount" => $ret["discount_amount"] ?? 0,
                            "buyer_id" => $ret["sub_openid"] ?? "",
                            "trade_no" => $ret["out_transaction_id"] ?? "",
                            "other_no" => $ret["leshua_order_id"] ?? "",
                            "pay_ways" => $ret["pay_way"] ?? ""
                        ]
                    ];

                } else if ($ret['status'] == 0) {
                    return [
                        'status' => 2,
                        'message' => '支付中',
                        'data' => [
                            "status" => $ret["status"],
                            "total_amount" => bcdiv((string)($ret["amount"] ?? 0), "100", 2),
                            "pay_amount" => bcdiv((string)($ret["buyer_pay_amount"] ?? $ret["amount"]), "100", 2),
                            "pay_time" => "",
                            "discount_amount" => $ret["discount_amount"] ?? 0,
                            "buyer_id" => $ret["sub_openid"] ?? "",
                            "trade_no" => $ret["out_transaction_id"] ?? "",
                            "other_no" => $ret["leshua_order_id"] ?? "",
                            "pay_ways" => $ret["pay_way"] ?? ""
                        ]
                    ];
                } else {
                    $message = $ret['error_msg'] ?? "失败了";
                    return [
                        'status' => 3,
                        'message' => $message,
                        "data" => [
                            "status" => $ret["status"],
                            "total_amount" => bcdiv((string)($ret["amount"] ?? 0), "100", 2),
                            "pay_amount" => bcdiv((string)($ret["buyer_pay_amount"] ?? $ret["amount"]), "100", 2),
                            "pay_time" => "",
                            "discount_amount" => $ret["discount_amount"] ?? 0,
                            "buyer_id" => $ret["sub_openid"] ?? "",
                            "trade_no" => $ret["out_transaction_id"] ?? "",
                            "other_no" => $ret["leshua_order_id"] ?? "",
                            "pay_ways" => $ret["pay_way"] ?? ""
                        ]
                    ];
                }
            } else {
                return [
                    'status' => 3,
                    'message' => '支付异常',
                ];
            }
        } catch (\Exception $ex) {
            return [
                'status' => '0',
                'message' => $ex->getMessage() . ' | ' . $ex->getLine(),
            ];
        }
    }


    //退款 0-系统错误 1-成功
    public function refund($data, $config)
    {
        try {
            $params = [
                'service' => "unified_refund",
                'sign_type' => "MD5",
                'merchant_id' => $data['mch_id'],
                'third_order_id' => $data['out_trade_no'],
//                'leshua_order_id' => $data["other_no"],
                "merchant_refund_id" => $data["refund_no"],
                "refund_amount" => bcmul((string)$data["refund_amount"], "100", 0),
                "refund_type" => 1,
                "attach" => json_encode([
                    'new_refund_amount' => $data['new_refund_amount'],
                    'new_fee_amount' => $data['new_fee_amount']
                ]),
                "nonce_str" => (string)(time() . rand(1000, 9999)),
                "notify_url" => url("api/leshuaunion/refund_notify_url"),
            ];
            $base = base::getInstance();

            $params["sign"] = $base->createSign($params, $config->key);

            $ret = $base->build($base::REFUND, $params, 'refund');

            if (empty($ret) || !is_array($ret) || !isset($ret["resp_code"])) {
                throw new BizException("请求失败");
            }
            if ($ret["resp_code"] != "0") {
                throw new BizException($ret["resp_msg"]);
            }

            if (isset($ret['result_code']) && $ret["result_code"] == 0) {
                Log::channel("leshuaunion")->info("refund_result_code", [
                    "res" => $ret
                ]);
//                10-退款中 11-退款成功 12-退款失败
                if ($ret["status"] == 10) {
                    sleep(2);
                    Log::channel("leshuaunion")->info("refund_query_params", [
                        "data" => [
                            "mch_id" => $data["mch_id"],
                            "out_trade_no" => $data["out_trade_no"],
                            //                        "other_no" => $data["other_no"],
                            "refund_no" => $data["refund_no"],
                            //                        "other_refund_no" => $data["other_refund_no"],
                        ],
                        "config" => $config
                    ]);
                    //查询数据
                    $refundQueryRes = $this->refund_query([
                        "mch_id" => $data["mch_id"],
                        "out_trade_no" => $data["out_trade_no"],
                        //                        "other_no" => $data["other_no"],
                        "refund_no" => $data["refund_no"],
                        //                        "other_refund_no" => $data["other_refund_no"],
                    ], $config);
                    Log::channel("leshuaunion")->info("refundQueryRes", [$refundQueryRes]);
                    if ($refundQueryRes["status"] == 1) {
                        return [
                            "status" => 1,
                            "message" => "退款成功",
                            "data" => [
                                'refund_count' => 1,
                                'out_trade_no' => $data['out_trade_no'],
                                "other_refund_no" => $refundQueryRes["data"]["leshua_refund_id"],
                                "refund_amount" => $refundQueryRes["data"]["refund_amount"],
                                "refund_detail" => $refundQueryRes["data"]["refund_detail"]
                            ]
                        ];
                    } else if ($refundQueryRes["status"] == 0) {
                        return [
                            "status" => 3,
                            "message" => "退款中",
                            "data" => [
                                'refund_count' => 1,
                                'out_trade_no' => $data['out_trade_no'],
                                "other_refund_no" => $refundQueryRes["data"]["leshua_refund_id"],
                                "refund_amount" => $refundQueryRes["data"]["refund_amount"],
                                "refund_detail" => $refundQueryRes["data"]["refund_detail"] ?? ""
                            ]
                        ];
                    } else {
                        return [
                            "status" => 2,
                            "message" => "退款失败"
                        ];
                    }
                } else if ($ret["status"] == 11) {
                    return [
                        "status" => 1,
                        "message" => "退款成功",
                        "data" => [
                            'refund_count' => 1,
                            'out_trade_no' => $data['out_trade_no'],
                            "other_refund_no" => $ret["leshua_refund_id"],
                            "refund_amount" => $ret["refund_amount"],
                            "refund_detail" => $ret["refund_detail"]
                        ]
                    ];
                } else if ($ret["status"] == 12) {
                    Log::channel("leshuaunion")->info("refund", [
                        "remark" => "退款失败",
                        "res" => $ret,
                    ]);
                    return [
                        "status" => 2,
                        "message" => "退款失败"
                    ];
                } else {
                    return [
                        "status" => 2,
                        "message" => "退款失败"
                    ];
                }
            } else {
                return [
                    'status' => 2,
                    'message' => $ret["error_msg"] ?? "退款失败"
                ];
            }
        } catch (\Exception $ex) {
            return [
                'status' => 0,
                'message' => $ex->getMessage() . ' | ' . $ex->getLine() . "|" . $ex->getFile()
            ];
        }
    }

    //退款查询 0-系统错误 1-成功 2-正在退款 3-失败
    public function refund_query($data, $config)
    {
        try {
            $params = [
                "service" => "unified_query_refund",
                "sign_type" => "MD5",
                "merchant_id" => $data["mch_id"],
                "third_order_id" => $data["out_trade_no"],
//                "leshua_order_id" => $data["other_no"],
                "merchant_refund_id" => $data["refund_no"],
//                "leshua_refund_id" => $data["other_refund_no"],
                "nonce_str" => (string)time() . rand(1000, 9999),
            ];
            $base = base::getInstance();
            $params["sign"] = $base->createSign($params, $config->key);
            $ret = $base->build($base::REFUND_QUERY, $params, 'refund_query');
            if (empty($ret) || !is_array($ret) || !isset($ret["resp_code"])) {
                throw new BizException("查询失败");
            }
            if ($ret["resp_code"] != 0) {
                throw new BizException($ret["resp_msg"]);
            }
            if ($ret["result_code"] != 0) {
                throw new BizException($ret["resp_msg"]);
            }
            if ($ret["status"] == 11) {
                return [
                    "status" => 1,
                    "message" => "退款成功",
                    "data" => $ret
                ];
            } else if ($ret["status"] == 10) {
                return [
                    "status" => 0,
                    "message" => "退款中",
                    "data" => $ret
                ];
            } else {
                return [
                    "status" => -1,
                    "message" => "退款失败",
                    "data" => $ret
                ];
            }
        } catch (\Exception $ex) {
            return [
                'status' => -1,
                'message' => $ex->getMessage()
            ];
        }
    }

    public function qr_submit($data, $config)
    {
        //获取马牌
        try {
//          WXZF WXZF UPSMZF
            $params = [
                "service" => "get_tdcode",
                "sign_type" => "MD5",
                "pay_way" => $data["pay_way"],
                "merchant_id" => $data["mch_id"],
                "third_order_id" => $data["out_trade_no"],
                "amount" => bcmul((string)$data["total_amount"], "100", 0),
                "jspay_flag" => 2,
                "nonce_str" => (string)time() . rand(1000, 9999),
                "notify_url" => url("api/leshuaunion/pay_notify_url"),
                "client_ip" => get_client_ip(),
                "order_expiration" => 300,
                "terminal_info" => json_encode([
                    "device_type" => "11",
                    "serial_num" => "lhsd" . $data["mch_id"],
                ]),
            ];
            Log::channel("leshuaunion")->info("qr_submit_start", $params);
            if (isset($data["goods_detail"]) && !empty($data["goods_detail"])) {
                $params["goods_detail"] = $data["goods_detail"];
            }
            //
            $params["sign"] = $this->createSign($params, $config->key);
            $base = base::getInstance();
//            $reqBody = $base->params($params, $data);
            $ret = $base->build($base::QR_SUBMIT, $params, 'qr_submit');
            if (empty($ret) || !is_array($ret) || !isset($ret["resp_code"])) {
                throw new BizException("请求失败");
            }
            if ($ret["resp_code"] != "0") {
                throw new BizException($ret["resp_msg"]);
            }
            if (isset($ret['result_code']) && $ret['result_code'] == 0) {
                return [
                    'status' => 1,
                    'message' => '退款成功',
                    'data' => [
                        'codeUrl' => $ret['jspay_url']
                    ]
                ];
            }
            return [
                'status' => 2,
                'message' => $ret["error_msg"] ?? "接口异常"
            ];
        } catch (\Exception $e) {
            return [
                'status' => 3,
                'message' => $e->getMessage() . ' | ' . $e->getLine(),
            ];
        }
    }


    public function embedPay(array $data, array $config): array
    {
        try {
            /**
             * "merchant_id" => $response["CUST_ID"],
             * "amount" => $data["total_amount"],
             * "third_order" => $data["orderNo"],
             * "shop_no" => $data["store_id"],
             * "attach" => [
             * "store_id" => $data["store_id"]
             * ]
             */
            $params = [
                "merchant_id" => $data["merchant_id"],
                "amount" => bcmul((string)$data["amount"], "100"),
                "pay_way" => 0,
                "notify_url" => $data["ASYNC_NOTIFY_IP"],
                "third_order" => $data["third_order"],
                "shop_no" => $data["shop_no"],
                "attach" => json_encode([
                    "store_id" => $data["shop_no"]
                ])
            ];
            $params["sign"] = $this->createSign($params, $config["key"]);
            $base = base::getInstance();
//            $reqBody = $base->params($params, $data);
            $ret = $base->buildwww($base::EmbedPay, $params, 'embedPay');
            if (empty($ret) || !is_array($ret) || !isset($ret["error_code"]) || !isset($ret["data"]["result_code"])) {
                throw new BizException($ret["error_msg"]??"请求失败");
            }
            if ($ret["data"]["result_code"] != 0) {
                throw new BizException($ret["data"]["result_msg"]);
            }
            $resData = [
                "merchant_id" => $ret["data"]["merchant_id"],
                "third_order" => $ret["data"]["third_order"],
                "pre_order" => $ret["data"]["pre_order"],
                "amount" => $ret["data"]["amount"],
                "result_code" => $ret["data"]["result_code"] ?? "",
                "result_msg" => $ret["data"]["result_msg"] ?? ""
            ];
            if ($resData["result_code"] != 0) {
                throw new BizException($resData["result_msg"]);
            }
            return [
                "status" => 1,
                "message" => "创建订单成功",
                "data" => $resData
            ];
        } catch (\Exception $e) {
            return [
                'status' => -1,
                'message' => $e->getMessage() ,
            ];
        }
    }


    public function embedQuery(array $data, array $config): array
    {
        try {
            $params = [
                "merchant_id" => $data["merchant_id"],
                "amount" => bcmul((string)$data["amount"], "100"),
                "pay_way" => 0,
                "notify_url" => $data["ASYNC_NOTIFY_IP"],
                "third_order" => $data["third_order"],
                "shop_no" => $data["shop_no"],
                "attach" => json_encode([
                    "store_id" => $data["shop_no"]
                ])
            ];
            $params["sign"] = $this->createSign($params, $config["key"]);
            $base = base::getInstance();
//            $reqBody = $base->params($params, $data);
            $ret = $base->buildwww($base::EmbedPay, $params, 'embedQuery');
            if (empty($ret) || !is_array($ret) || !isset($ret["error_code"]) || !isset($ret["data"]["result_code"])) {
                throw new BizException("请求失败");
            }
            if ($ret["data"]["result_code"] != 0) {
                throw new BizException($ret["data"]["result_msg"]);
            }
            return [
                "status" => 1,
                "message" => "创建订单成功",
                "data" => ""
            ];
        } catch (\Exception $e) {
            return [
                "status" => -1,
                "message" => $e->getMessage() . ' | ' . $e->getLine() . "|" . $e->getFile(),
            ];
        }
    }

}
